package com.duojuhe.common.utils.iputil;


import com.duojuhe.common.constant.SingleStringConstant;
import com.duojuhe.common.utils.regexutil.RegexUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.xdb.Searcher;

import java.io.FileInputStream;
import java.io.InputStream;

import org.springframework.util.FileCopyUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;


/**
 * @ClassName: IPUtil
 * @Desc: Ip工具类
 * @date 2013年4月1日
 */
@Slf4j
public class IPUtils {
    /**
     * 初始化离线ip数据库字节
     */
    private static Searcher searcher = null;

    //系统默认ip
    private final static String DEFAULT_IP = "127.0.0.1";


    /**
     * 初始化 离线ip Searcher对象流
     *
     * @param filePath
     * @throws Exception
     */
    public static void initIp2regionXdbSearcher(String filePath) throws Exception {
        if (searcher != null || StringUtils.isBlank(filePath)) {
            return;
        }
        InputStream inputStream = new FileInputStream(filePath);
        byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
        // 创建一个完全基于内存的查询对象
        searcher = Searcher.newWithBuffer(dbBinStr);
    }

    /**
     * 根据ip从 ip2region.xdb 中获取地理位置
     * 数据格式： 国家|区域|省份|城市|ISP
     * 192.168.31.160 0|0|0|内网IP|内网IP
     * 47.52.236.180 中国|0|香港|0|阿里云
     * 220.248.12.158 中国|0|上海|上海市|联通
     * 164.114.53.60 美国|0|华盛顿|0|0
     *
     * @param ip
     * @return 地理位置 国家|区域|省份|城市|ISP
     */
    public static String getIpInfo(String ip) {
        try {
            if (!RegexUtil.validIp(ip) || searcher == null) {
                return StringUtils.EMPTY;
            }
            StringBuilder sb = new StringBuilder();
            String searchIpInfo = searcher.search(ip);
            String[] splitIpInfo = searchIpInfo.split(SingleStringConstant.VERTICAL_LINE);
            log.debug("IP：{}，Info：{}", ip, splitIpInfo);
            if (DEFAULT_IP.equals(ip)) {
                return splitIpInfo[3];
            }
            //分割符号
            String LINE = "|";
            sb.append(splitIpInfo[0]).append(LINE);
            sb.append(splitIpInfo[1]).append(LINE);
            sb.append(splitIpInfo[2]).append(LINE);
            sb.append(splitIpInfo[3]).append(LINE);
            sb.append(splitIpInfo[4]);
            return sb.toString().replace(LINE + "0", StringUtils.EMPTY).replace("0" + LINE, StringUtils.EMPTY);
        } catch (Exception e) {
            log.info("failed to search ip:{}", ip, e);
            return StringUtils.EMPTY;
        }
    }

    /**
     * 获取ip地址
     *
     * @param request
     * @return
     */
    public static String getClientIP(HttpServletRequest request) {
        try {
            String fromSource = "x-real-ip";
            String ip = request.getHeader("x-real-ip");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("x-forwarded-for");
                fromSource = "x-forwarded-for";
            }

            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("proxy-client-ip");
                fromSource = "proxy-client-ip";
            }

            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("wl-proxy-client-ip");
                fromSource = "wl-proxy-client-ip";
            }

            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                fromSource = "request.getRemoteAddr";
            }
            log.debug("get client ip, ip = {}, source = {}", ip, fromSource);
            if (StringUtils.isNotEmpty(ip)) {
                if (ip.indexOf(",") > 0) {
                    ip = ip.split(",")[0];
                }
            }
            return ip;
        } catch (Exception e) {
            log.error("获取ip地址出现异常", e);
            return DEFAULT_IP;
        }
    }


    /**
     * 网站后台专用获取ip地址【网站后台专用】
     *
     * @param request
     * @return
     */
    public static String getClientIPByIpHeader(HttpServletRequest request, String ipHeader) {
        try {
            if (StringUtils.isBlank(ipHeader)) {
                return getClientIP(request);
            }
            //ip请求头
            for (String header : ipHeader.split(",")) {
                String ip = request.getHeader(header);
                if (StringUtils.isNotBlank(ip) && ip.length() > 0 && !"unknown".equalsIgnoreCase(ip)) {
                    log.info("get admin client ip, ip = {}, source = {}", ip, header);
                    return ip;
                }
            }
            String ip = request.getRemoteAddr();
            if (StringUtils.isNotBlank(ip) && ip.length() > 0 && !"unknown".equalsIgnoreCase(ip)) {
                log.info("get admin client ip, ip = {}, source = {}", ip, "request.getRemoteAddr");
                return ip;
            }
            return DEFAULT_IP;
        } catch (Exception e) {
            log.error("获取ip地址出现异常:", e);
            return DEFAULT_IP;
        }
    }

    /**
     * 获取本地ip
     *
     * @return
     */
    public static String getHostIp() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return DEFAULT_IP;
        }
    }

    /**
     * 获取地址
     *
     * @return
     */
    public static String getHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return "未知";
        }
    }



    /**
     * 判断 ip 是 ipv4 false 还是 ipv6 true
     *
     * @param address
     * @return
     */
    public static boolean isIpv6Address(String address) {
        try {
            final InetAddress inetAddress = InetAddress.getByName(address);
            return inetAddress instanceof Inet6Address;
        } catch (UnknownHostException e) {
            return false;
        }
    }
}

